#ifndef GPLIB_H_
#define GPLIB_H_

#include <stddef.h>

#define GP_OK  0
#define GP_ERR 1
//#define __BYTE_REORDER__
//const int bReorder = 0;
//const int g_nByteOffset[4] = { 3, 1, -1, -3 };
//const int g_nMaxPairsOfCoord = 24;
#ifdef __BYTE_REODRER__
     #define BYTE_REORDER(b) ((b) + g_nByteOffset[(int)(b) & 3])
#else
	#define BYTE_REORDER(b) (b)
#endif
#define GET_PIXEL_PTR_8(pData, nX, nY, nBytesPerLine) ((pData) + (nY) * (nBytesPerLine) + (nX))
#define GET_PIXEL_PTR_16(pData, nX, nY, nBytesPerLine) ((pData) + (nY) * (nBytesPerLine) + (nX) * 2)
#define GET_PIXEL_PTR_24(pData, nX, nY, nBytesPerLine) ((pData) + (nY) * (nBytesPerLine) + (nX) * 3)

typedef struct TColor {
	char b1, b2, b3, b4;
} TColor;

#define SET_PIXEL_8(pScrPtr, pColor) *BYTE_REORDER(pScrPtr) = *((char *)(pColor));
#define SET_PIXEL_16(pScrPtr, pColor)						\
	*BYTE_REORDER(pScrPtr    ) = *((char *)(pColor)    );	\
	*BYTE_REORDER(pScrPtr + 1) = *((char *)(pColor) + 1);
#define SET_PIXEL_24(pScrPtr, pColor)						\
	*BYTE_REORDER(pScrPtr    ) = *((char *)(pColor)    );	\
	*BYTE_REORDER(pScrPtr + 1) = *((char *)(pColor) + 1);	\
	*BYTE_REORDER(pScrPtr + 2) = *((char *)(pColor) + 2);

#define SET_XOR_PIXEL_8(pScrPtr, pColor) *BYTE_REORDER(pScrPtr) ^= *((char *)(pColor));
#define SET_XOR_PIXEL_16(pScrPtr, pColor)					\
	*BYTE_REORDER(pScrPtr    ) ^= *((char *)(pColor)    );	\
	*BYTE_REORDER(pScrPtr + 1) ^= *((char *)(pColor) + 1);
#define SET_XOR_PIXEL_24(pScrPtr, pColor)					\
	*BYTE_REORDER(pScrPtr    ) ^= *((char *)(pColor)    );	\
	*BYTE_REORDER(pScrPtr + 1) ^= *((char *)(pColor) + 1);	\
	*BYTE_REORDER(pScrPtr + 2) ^= *((char *)(pColor) + 2);

#define SET_MASKED_PIXEL_8(pScrPtr, pColor) 	\
	if (nLineMask & nCurrentPos) {				\
		SET_PIXEL_8(pScrPtr, pColor); 			\
	}											\
	nCurrentPos <<= 1; 							\
												\
	if (nCurrentPos == nLineMaskPos) {			\
		nCurrentPos = 1;						\
	}
#define SET_MASKED_PIXEL_16(pScrPtr, pColor) 	\
	if (nLineMask & nCurrentPos) {				\
		SET_PIXEL_16(pScrPtr, pColor); 			\
	}											\
	nCurrentPos <<= 1; 							\
												\
	if (nCurrentPos == nLineMaskPos) {			\
		nCurrentPos = 1;						\
	}
#define SET_MASKED_PIXEL_24(pScrPtr, pColor) 	\
	if (nLineMask & nCurrentPos) {				\
		SET_PIXEL_24(pScrPtr, pColor); 			\
	}											\
	nCurrentPos <<= 1; 							\
												\
	if (nCurrentPos == nLineMaskPos) {			\
		nCurrentPos = 1;						\
	}

#define DEBUG

#ifdef DEBUG
# define debug(s) printf s
#else
# define debug(s)
#endif

typedef struct TIcon {
	size_t nWidth;
	size_t nHeight;
	unsigned char *pData;
} TIcon;

typedef struct TFont
{
      unsigned int nWidth;
      unsigned int nHeight;
      unsigned int nBitsInLastByte;
      unsigned int nBytesPerSymbolLine;
      unsigned char *pData;
} TFont;

typedef struct TGraphicContext {
	char *pData;
	size_t nSize;
	int nScreenSizeX;
	int nScreenSizeY;
	unsigned nBytesPerLine;

	int nLastPositionX;
	int nLastPositionY;
	char *pLastScreenPos;

	char bReorder;
	char nBitsPerPixel;

	TFont *pCurrFont;

	unsigned int nLineMask;
	unsigned int nCurrentPos;
	unsigned int nLineMaskPos;

	char nCurrentThickness;
	int nThOffsX;
	int nThOffsY;
	int nThOffsX100;
	char bRecalcThick;
	char bSimpleRecalcThick;
	char bDrawAddonPixel;

	char **ppPointsArray;
	int nPointsANumber;
	char ***pppRowIndexes;
} TGraphicContext;

int InitGContext(TGraphicContext *, char *, size_t, int, int, char, char);
int MoveTo(TGraphicContext *, int, int);
int SetPixel(TGraphicContext *, int, int, TColor);
int LineTo(TGraphicContext *,  int, int, TColor);
int XorLineTo(TGraphicContext *, int, int, TColor);
int ResetCurrentPos(TGraphicContext *);
int SetThickness(TGraphicContext *, char);
int SetLineMask(TGraphicContext *, unsigned int, unsigned int);
int ThickLineTo(TGraphicContext *, int, int, TColor);
int QuickThickLineTo(TGraphicContext *, int, int, TColor);
int MaskLineTo(TGraphicContext *, int, int, TColor);
int DrawPoly(TGraphicContext *, int, int *, TColor, TColor);
int Rectangle(TGraphicContext *, int ,int, int, int, TColor);
int FillRectangle(TGraphicContext *, int, int, int, int, TColor);
int DrawMaskRect(TGraphicContext *, int ,int, int, int, TColor);
int DrawReliefRect(TGraphicContext *, int ,int, int, int, TColor, TColor, char);

//окружности

void Circle(TGraphicContext* ctx, int x,int y,int r,char color);
void Circle1(TGraphicContext* ctx, int x,int y,int r,char color);
void FillCircle(TGraphicContext* ctx, int x,int y,int r,char color);
void Arc(TGraphicContext* ctx,int xc,int yc,int r,double sa,double ea,char color);

void DrawBitmap(TGraphicContext* ctx, int XC,int YC, int CX, int CY, char Color, const unsigned char *BitsPtr,float cosAngle,float sinAngle);
void StretchBitmap(TGraphicContext* ctx, int CenterX,int CenterY,int ImageWidth,int ImageHeight,char Color, const char* Bits,float CosAngle,float SinAngle);
void DrawIcon(TGraphicContext* ctx, int x, int y, struct TIcon* pIcon);
void DrawCutIcon(TGraphicContext* ctx, int x, int y, struct TIcon* pIcon);
void DrawIconMono(TGraphicContext* ctx, int x, int y, struct TIcon* pIcon, char Color);
void DrawPixmap(TGraphicContext* ctx, int x, int y, struct TIcon* pIcon);


// Шрифты
const struct TFont* SetFont(TGraphicContext* ctx,const struct TFont* pFont);
void OutChar(TGraphicContext* ctx, unsigned char Symbol,char Color);
void OutCharBackground(TGraphicContext* ctx, unsigned char Symbol,char TextColor, char BackgroundColor);
void OutCharBackground1(TGraphicContext* ctx, unsigned char Symbol,char Color, char BackgroundColor);
void OutText(TGraphicContext* ctx,const char *string,char color,int length);
void OutTextBackground(TGraphicContext* ctx,const char *string,int length,char color,char colorB);
void OutFormatText(TGraphicContext* ctx, char color,const char *format,...);
void OutFormatTextB(TGraphicContext* ctx, char color,char colorB,const char *format,...);

#endif /* GPLIB_H_ */
